﻿using System;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Threading;
using Slippor.Utility.WebWorker;
using System.Web;

namespace Slippor.Douban.Radio.Assist
{
    public class RadioVersion
    {
        private readonly String _versionCode = "0.0.0.0";
        private String _downloadUrl = String.Empty;
        private String _versionDes = String.Empty;

        private String _versionMark = String.Empty;

        public RadioVersion(String versionCode)
        {
            IsLatest = false;
            _versionCode = versionCode;
        }

        public static RadioVersion CurrentVersion
        {
            get { return new RadioVersion("4.5.0104.2"); }
        }

        public String VersionCode
        {
            get { return _versionCode; }
        }

        public String VersionMark
        {
            get { return _versionMark; }
            set { _versionMark = value; }
        }

        public String VersionDes
        {
            get { return _versionDes; }
            set { _versionDes = value; }
        }

        public String DownloadUrl
        {
            get { return _downloadUrl; }
            set { _downloadUrl = value; }
        }

        public bool IsLatest { get; set; }

        public bool IsNewer(RadioVersion olderVersion)
        {
            String[] versionCodes = _versionCode.Split('.');
            String[] currentCodes = olderVersion._versionCode.Split('.');
            if (versionCodes.Length != currentCodes.Length)
            {
                return true;
            }
            for (int i = 0; i < versionCodes.Length; i++)
            {
                int v = Convert.ToInt16(versionCodes[i]);
                int nv = Convert.ToInt16(currentCodes[i]);
                if (nv < v)
                {
                    return true;
                }
                if (nv > v)
                {
                    return false;
                }
            }
            return false;
        }
    }

    public static class VersionControl
    {
        private const String _requestUrl = "http://www.box.net/shared/36j5cedz95";
        private const String _newestUrl = "http://slippor.blogbus.com/logs/63221196.html";
        private static RadioVersion _latesVersion = new RadioVersion("0.0.0.0");

        private static bool _isChecking;
        private static VersionCheckCompleted _versionCheckCompleted;

        public static bool IsChecking
        {
            get { return _isChecking; }
        }

        private static RadioVersion GetVersion(RadioVersion version)
        {
            int tryTime = 5;
            using (var webWorker = new BoxNetWebWorker())
            {
                while (tryTime > 0)
                {
                    try
                    {
                        string doc = webWorker.AchieveResponse(_requestUrl, null, null, true, RequestMethod.Get);
                        string pattern =
                            String.Format(@"Latest=(?<L>[\w\W]*?)\|[\w\W]*?Down=(?<U>[\w\W]*?)\|[\w\W]*?Des=(?<DES>[\w\W]*?)<");
                        Match match = Regex.Match(doc, pattern);
                        if (match.Success)
                        {
                            _latesVersion = new RadioVersion(match.Groups["L"].Value.TrimEnd('|'))
                                                {
                                                    VersionMark = version.VersionMark,
                                                    VersionDes =
                                                        HttpUtility.HtmlDecode(match.Groups["DES"].Value.TrimEnd('|').Replace("##", "\n")),
                                                    DownloadUrl = match.Groups["U"].Value.TrimEnd('|')
                                                };
                        }
                        else
                        {
                            _latesVersion = new RadioVersion("10.0.0.0")
                            {
                                VersionMark = version.VersionMark,
                                VersionDes = AssistStringResource.Message_VersionTooLow,
                                DownloadUrl = _newestUrl
                            };
                        }
                        tryTime = 0;
                        return _latesVersion;
                    }
                    catch
                    {
                        tryTime--;
                        Thread.Sleep(1000);
                    }
                }
                return new RadioVersion("10.0.0.0")
                {
                    VersionMark = version.VersionMark,
                    VersionDes = AssistStringResource.Message_VersionFailed,
                    DownloadUrl = _newestUrl
                }; 
            }
        }

        public static void CheckVersion(RadioVersion currentVersion, VersionCheckCompleted versionCheckCompleted)
        {
            if (_isChecking)
            {
            }
            else
            {
                _versionCheckCompleted = versionCheckCompleted;
                _isChecking = true;
                var versionWorker = new BackgroundWorker();
                versionWorker.DoWork += versionWorker_DoWork;
                versionWorker.RunWorkerCompleted += versionWorker_RunWorkerCompleted;
                versionWorker.RunWorkerAsync(currentVersion);
            }
        }

        private static void versionWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _isChecking = false;
            if (e.Error == null && e.Result != null)
            {
                var newVersion = e.Result as RadioVersion;
                if (_versionCheckCompleted != null)
                {
                    _versionCheckCompleted(newVersion);
                }
            }
            ((BackgroundWorker) sender).Dispose();
        }

        private static void versionWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = GetVersion(e.Argument as RadioVersion);
        }
    }

    public delegate void VersionCheckCompleted(RadioVersion latestVersion);
}